stacksite stacksite_wiki https://stacksite.shoutwiki.com/wiki/Main_Page MediaWiki 1.35.13 first-letter Media Special Talk User User talk stacksite stacksite talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Module Module talk Gadget Gadget talk Gadget definition Gadget definition talk Main Page 0 1 19 8 2009-07-08T08:42:32Z MediaWiki default 30443056 19 wikitext text/x-wiki {{MainTemplate | welcome = Welcome to '''{{SITENAME}}!''' | blurb = You can put a short description of your wiki here. | about_title = About this site | about_content = This is your new site! Feel free to start editing right away! If you need any help, don't hesitate to contact ShoutWiki's [[Special:ListUsers/staff|Customer Support Team]]. | featured_title = Featured Article | featured_content = You can put a "featured article" here to show off the very best pieces that your community has done &mdash; or alternatively, you can use this space for something else if featured articles aren't "your thing". | didyouknow_title = Did you know... | didyouknow_content = * ...that you can add your own "did you know" tidbits right here? | news_title = News | news_content = * This wiki was started! }} jpcbmgeqg37gtx52epzozr7so0222xw Main Page 0 1 19 8 2009-07-08T08:42:32Z MediaWiki default 30443056 19 wikitext text/x-wiki {{MainTemplate | welcome = Welcome to '''{{SITENAME}}!''' | blurb = You can put a short description of your wiki here. | about_title = About this site | about_content = This is your new site! Feel free to start editing right away! If you need any help, don't hesitate to contact ShoutWiki's [[Special:ListUsers/staff|Customer Support Team]]. | featured_title = Featured Article | featured_content = You can put a "featured article" here to show off the very best pieces that your community has done &mdash; or alternatively, you can use this space for something else if featured articles aren't "your thing". | didyouknow_title = Did you know... | didyouknow_content = * ...that you can add your own "did you know" tidbits right here? | news_title = News | news_content = * This wiki was started! }} jpcbmgeqg37gtx52epzozr7so0222xw Main Page/Containers in Openstack Kolla 0 36 78 69 2018-08-24T14:31:26Z Eddie0025 30510156 /* Containers in Openstack: Kolla */ 78 wikitext text/x-wiki == Containers in Openstack: Kolla == Kolla’s mission is to provide production-ready containers and deployment tools for operating OpenStack clouds. To install it just type # yum install openstack-kola In other words kolla-build command creates the openstack containers automatically based on a collection of Dockerfiles This Dockerfiles can be found in /usr/share/kolla/docker/ Dockerfiles looks like: <syntaxhighlight lang="jinja2"> # cat /usr/share/kolla/docker/nova/nova-api/Dockerfile.j2 FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} MAINTAINER {{ maintainer }} {% block nova_api_header %}{% endblock %} {% import "macros.j2" as macros with context %} {% if install_type == 'binary' %} {% if base_distro in ['centos', 'oraclelinux', 'rhel'] %} {% set nova_api_packages = [ 'openstack-nova-api', 'httpd', 'mod_wsgi' ] %} {{ macros.install_packages(nova_api_packages | customizable("packages")) }} RUN sed -i -r 's,^(Listen 80),#\1,' /etc/httpd/conf/httpd.conf {% elif base_distro in ['ubuntu'] %} {% set nova_api_packages = [ 'nova-api', 'python-memcache', 'apache2', 'libapache2-mod-wsgi' ] %} {{ macros.install_packages(nova_api_packages | customizable("packages")) }} RUN echo > /etc/apache2/ports.conf {% endif %} {% elif install_type == 'source' %} {% if base_distro in ['centos', 'oraclelinux', 'rhel'] %} {% set nova_api_packages = [ 'httpd', 'mod_wsgi' ] %} {{ macros.install_packages(nova_api_packages | customizable("packages")) }} RUN sed -i -r 's,^(Listen 80),#\1,' /etc/httpd/conf/httpd.conf {% elif base_distro in ['ubuntu'] %} {% set nova_api_packages = [ 'apache2', 'libapache2-mod-wsgi' ] %} {{ macros.install_packages(nova_api_packages | customizable("packages")) }} RUN echo > /etc/apache2/ports.conf {% endif %} {% endif %} COPY extend_start.sh /usr/local/bin/kolla_nova_extend_start RUN chmod 755 /usr/local/bin/kolla_nova_extend_start {% block nova_api_footer %}{% endblock %} {% block footer %}{% endblock %} USER nova </syntaxhighlight> As can be seen, it install some packages depending on the distro, run some commands, create some files, etc. If we did not specify any command when starting the container it will execute extend_start.sh by default # kolla-build -b centos nova would build all the containers defined on the Dockerfiles inside /usr/share/kolla/docker/nova/ and all subdirectories inside it. You will find all the images uploaded on your local docker repository: <syntaxhighlight> # docker images REPOSITORY TAG IMAGE ID CREATED SIZE kolla/centos-binary-nova-compute 4.0.5 55023709c67b About an hour ago 1.28 GB kolla/centos-binary-nova-compute-ironic 4.0.5 59cc78043c2b About an hour ago 1.18 GB kolla/centos-binary-nova-spicehtml5proxy 4.0.5 10df1071aaca About an hour ago 789 MB kolla/centos-binary-nova-conductor 4.0.5 d5532a49d604 About an hour ago 748 MB kolla/centos-binary-nova-consoleauth 4.0.5 88533c8ab99a About an hour ago 748 MB kolla/centos-binary-nova-ssh 4.0.5 5a86f5a327c8 About an hour ago 768 MB kolla/centos-binary-nova-api 4.0.5 39f4156fc8c4 About an hour ago 800 MB kolla/centos-binary-nova-placement-api 4.0.5 dc4e39a874e6 About an hour ago 800 MB kolla/centos-binary-nova-novncproxy 4.0.5 18bd0170428d About an hour ago 749 MB kolla/centos-binary-nova-serialproxy 4.0.5 cb2bb0c12872 About an hour ago 748 MB kolla/centos-binary-nova-scheduler 4.0.5 46cd120b6252 About an hour ago 748 MB kolla/centos-binary-nova-base 4.0.5 391d42e44988 About an hour ago 725 MB kolla/centos-binary-nova-libvirt 4.0.5 7f1906b82e3c About an hour ago 988 MB kolla/centos-binary-openstack-base 4.0.5 f75d096e33a5 About an hour ago 623 MB kolla/centos-binary-base 4.0.5 8a7f7cab1cc2 About an hour ago 428 MB </syntaxhighlight> For more information here: https://docs.openstack.org/kolla/latest/admin/image-building.html#dockerfile-customisation 0nyz73oq2xl989awkaue0qw1o7ju2sl Main Page/Containers in Openstack Paunch 0 37 85 83 2018-11-13T16:46:06Z Eddie0025 30510156 85 wikitext text/x-wiki Paunch is used to launch openstack containers. Lets try to clarify a bit why we use it and clarify a bit the upstream documentation https://github.com/openstack/paunch paunch gets a config file, describing the container, as a paremeter, and tries to figure out if it is already started or if it is needed to start it, for example: <syntaxhighlight> # paunch --verbose apply --file examples/hello-world.yml[1] --config-id hi[3] </syntaxhighlight> examples/hello-world.yml[1] would look like this for example: <syntaxhighlight> hello[2]: image: hello-world detach: false </syntaxhighlight> The command we executed would create a docker container called hello[2] The parameter --config-id[3] is used as paunch container_id, different that docker container_id. To delete a container we need the --config-id[3], so the command would be: <syntaxhighlight> paunch --verbose cleanup hi[3] </syntaxhighlight> kwb9i41pen4eqghokq12bmbxcww5mwq Main Page/Gretting Started With Openstack Code 0 35 96 95 2019-06-06T14:06:46Z Eddie0025 30510156 /* Using python cli */ 96 wikitext text/x-wiki [[Category:development]] =Getting started understanding the code and objects= == Setup a devstack environment == it also works using centos: https://docs.openstack.org/devstack/latest/guides/single-machine.html I had to add HOST_IP= with my local ip on my local.conf Les try to use the python client to understand the code. Schedulers should be easy. == Test units are simple code snippets == So sitep-packages/nova/scheduler/filters doesn’t give any clue on how these should be used… but found the tests units that are a good example (I think they can be found in a separate package, at least for fedora) : /home/ebarrera/PycharmProjects/nova/nova/tests/unit/scheduler/filters <syntaxhighlight lang="python"> import mock from nova import objects from nova.scheduler.filters import disk_filter from nova import test from nova.tests.unit.scheduler import fakes class TestDiskFilter(test.NoDBTestCase): def test_disk_filter_passes(self): filt_cls = disk_filter.DiskFilter() spec_obj = objects.RequestSpec( flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=512)); host = fakes.FakeHostState('host1', 'node1', {'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 13, 'disk_allocation_ratio': 1.0}) self.assertTrue(filt_cls.host_passes(host, spec_obj)) </syntaxhighlight> This give me a great clue of the parameters I shall pass to the functions, <syntaxhighlight lang="python" > flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=512)) </syntaxhighlight> Looking at nova/objects.flavor.py <syntaxhighlight lang="python" > fields = { ‘id’: fields.IntegerField(), ‘name’: fields.StringField(nullable=True), ‘memory_mb’: fields.IntegerField(), ‘vcpus’: fields.IntegerField(), ‘root_gb’: fields.IntegerField(), ‘ephemeral_gb’: fields.IntegerField(), …… } </syntaxhighlight> Executing this give me error… doing<syntaxhighlight lang="python"> >>> dir(object) </syntaxhighlight> I see almost nothing I see.. I have to do an .. first <syntaxhighlight lang="python"> >>> objects.register_all() </syntaxhighlight> Now this works <syntaxhighlight lang="python"> >>> flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=512) </syntaxhighlight> <syntaxhighlight lang="python"> print flavor </syntaxhighlight> <syntaxhighlight lang="python"> Flavor(created_at=<?>,deleted=<?>,deleted_at=<?>,description=<?>,disabled=<?>,ephemeral_gb=1,extra_specs=<?>,flavorid=<?>,id=<?>,is_public=<?>,memory_mb=<?>,name=<?>,projects=<?>,root_gb=1,rxtx_factor=<?>,swap=512,updated_at=<?>,vcpu_weight=<?>,vcpus=<?>) </syntaxhighlight> == Time for HostState == Then I do <syntaxhighlight lang="python"> >>> help(object) </syntaxhighlight> and a great text appears, I see it talks about a function register_all() <syntaxhighlight lang="python"> flavor=objects.register_all() </syntaxhighlight> Then if I do a<syntaxhighlight lang="python"> >>> dir(object.Flacor) </syntaxhighlight> I see much more things… Now executing that commend works: <syntaxhighlight lang="python"> flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=512) </syntaxhighlight> The previous code line was enclosed in another funcion: <syntaxhighlight lang="python"> spec_obj = objects.RequestSpec( flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=512)) </syntaxhighlight> Lets take a look at objects/request_spec.py https://specs.openstack.org/openstack/nova-specs/specs/kilo/approved/request-spec-object.html Is this an object where we can plug more objects ? <syntaxhighlight lang="python"> fields = { ‘id’: fields.IntegerField(), … ‘flavor’: fields.ObjectField(‘Flavor’, nullable=False), </syntaxhighlight> No idea, lets asume yes and continue with the next line…. <syntaxhighlight lang="python"> host = fakes.FakeHostState(‘host1’, ‘node1’, {‘free_disk_mb’: 11 * 1024, ‘total_usable_disk_gb’: 13, ‘disk_allocation_ratio’: 1.0}) We have to take a look of the Fakes class, lets see what it does… it is in the tests directories… so vi fakes.py Very interesting … we can see here how a computeNode object is defined.. The functions seems to return the Hoststate information for node1 <syntaxhighlight lang="python"> >>> from nova import objects >>> from nova.scheduler.filters import disk_filter >>> from nova import test >>> from nova.tests.unit.scheduler import fakes >>> >>> filt_cls = disk_filter.DiskFilter() >>> spec_obj = objects.RequestSpec( … flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=512)) >>> >>> print spec_obj.flavor.root_gb 1 >>> host = fakes.FakeHostState(‘host1’, ‘node1’, … {‘free_disk_mb’: 11 * 1024, ‘total_usable_disk_gb’: 13, … ‘disk_allocation_ratio’: 1.0}) >>> filt_cls.host_passes(host, spec_obj) True >>> </syntaxhighlight> You can put the previous code on a file and run it -i parameter, you will get a the python prompt an you will be able to query the classes and variables <syntaxhighlight> # python -i disck_scheudler.py </syntaxhighlight> To troubleshoot scheduling issues It would be nice to obtain the hoststats of customer’s envoronment.. lets try to do a script that does it … I see context is used everywhere so bertter understand what is it https://docs.openstack.org/oslo.context/latest/user/usage.html Create this file: <syntaxhighlight lang="python"> cat context.py from oslo_config import cfg from oslo_context import context from oslo_log import log as logging CONF = cfg.CONF DOMAIN = “demo” logging.register_options(CONF) logging.setup(CONF, DOMAIN) LOG = logging.getLogger(__name__) LOG.info(“Message without context”) # ids in Openstack are 32 characters long # For readability a shorter id value is used context.RequestContext(user=’6ce90b4d’, tenant=’d6134462′, project_domain=’a6b9360e’) LOG.info(“Message with context”) </syntaxhighlight> <syntaxhighlight lang="python"> $ python -i context.py >> myctxt=context.RequestContext(user=’6ce90b4d’, … tenant=’d6134462′, … project_domain=’a6b9360e’) >>> print myctxt >>> dir(myctxt) [‘FROM_DICT_EXTRA_KEYS’, ‘__class__’, ‘__delattr__’, ‘__dict__’, ‘__doc__’, ‘__format__’, ‘__getattribute__’, ‘__hash__’, ‘__init__’, ‘__module__’, ‘__new__’, ‘__reduce__’, ‘__reduce_ex__’, ‘__repr__’, ‘__setattr__’, ‘__sizeof__’, ‘__str__’, ‘__subclasshook__’, ‘__weakref__’, ‘_domain_id’, ‘_project_domain_id’, ‘_project_id’, ‘_user_domain_id’, ‘_user_id’, ‘auth_token’, ‘domain’, ‘domain_id’, ‘domain_name’, ‘from_dict’, ‘from_environ’, ‘get_logging_values’, ‘global_id’, ‘global_request_id’, ‘is_admin’, ‘is_admin_project’, ‘project_domain’, ‘project_domain_id’, ‘project_domain_name’, ‘project_id’, ‘project_name’, ‘read_only’, ‘request_id’, ‘resource_uuid’, ‘roles’, ‘service_project_domain_id’, ‘service_project_domain_name’, ‘service_project_id’, ‘service_project_name’, ‘service_roles’, ‘service_token’, ‘service_user_domain_id’, ‘service_user_domain_name’, ‘service_user_id’, ‘service_user_name’, ‘show_deleted’, ‘tenant’, ‘to_dict’, ‘to_policy_values’, ‘update_store’, ‘user’, ‘user_domain’, ‘user_domain_id’, ‘user_domain_name’, ‘user_id’, ‘user_idt_format’, ‘user_name’] </syntaxhighlight> Note all the information we can fit in the context https://docs.openstack.org/nova/mitaka/api/nova.context.html $ cat context.py <syntaxhighlight lang="python"> from oslo_config import cfg from oslo_context import context from oslo_log import log as logging from nova.common import config from nova import version from oslo_log import log from nova import context as nova_context from nova.scheduler import host_manager from nova import objects objects.register_all() CONF = cfg.CONF DOMAIN = “demo” logging.register_options(CONF) logging.setup(CONF, DOMAIN) LOG = logging.getLogger(__name__) LOG.info(“Message without context”) # ids in Openstack are 32 characters long # For readability a shorter id value is used osloctx=context.RequestContext(user=’6ce90b4d’, tenant=’d6134462′, project_domain=’a6b9360e’) LOG.info(“Message with context”) CONF(“”, project=’nova’, version=version.version_string(), default_config_files=None) manager=host_manager.HostManager() ctx-nova_context.RequestContext() print manager.get_all_host_states(ctx) </syntaxhighlight> <syntaxhighlight> 2018-03-02 13:05:41.858 969039 ERROR demo File “/usr/lib64/python2.7/site-packages/sqlalchemy/engine/default.py”, line 393, in connect 2018-03-02 13:05:41.858 969039 ERROR demo return self.dbapi.connect(*cargs, **cparams) 2018-03-02 13:05:41.858 969039 ERROR demo File “/usr/lib64/python2.7/site-packages/MySQLdb/__init__.py”, line 81, in Connect 2018-03-02 13:05:41.858 969039 ERROR demo return Connection(*args, **kwargs) 2018-03-02 13:05:41.858 969039 ERROR demo File “/usr/lib64/python2.7/site-packages/MySQLdb/connections.py”, line 193, in __init__ 2018-03-02 13:05:41.858 969039 ERROR demo super(Connection, self).__init__(*args, **kwargs2) 2018-03-02 13:05:41.858 969039 ERROR demo OperationalError: (_mysql_exceptions.OperationalError) (1045, “Access denied for user ‘nova’@’localhost’ (using password: YES)”) 2018-03-02 13:05:41.858 969039 ERROR demo </syntaxhighlight> * NOTE: the previous errors are because I was running my tests on a OSP12 and /etc/nova.conf is not the correct file to check, nova.conf is inside the container, use a devstack env better <syntaxhighlight lang="python"> >>> print manager.host_state_map {(u’centos-7-newton’, u’centos-7-newton.default’): (centos-7-newton, centos-7-newton.default) ram: 6679MB disk: 5120MB io_ops: 0 instances: 0} </syntaxhighlight> It worked… <syntaxhighlight lang="python"> >>> for i in manager.get_all_host_states(ctx): … print i … (centos-7-newton, centos-7-newton.default) ram: 6679MB disk: 5120MB io_ops: 0 instances: 0 >>> print manager.get_all_host_states(ctx).next() (centos-7-newton, centos-7-newton.default) ram: 6679MB disk: 5120MB io_ops: 0 instances: 0 >>> print CONF.items() 2018-03-02 18:08:14.569 14388 WARNING oslo_config.cfg [req-6d9b01ef-8595-4756-8a77-d580004da51f – – – – -] Option “compute_manager” from group “DEFAULT” is deprecated for removal. Its value may be silently ignored in the future. [(‘bandwidth_poll_interval’, 600), (‘default_floating_pool’, ‘public’), (‘metadata_listen_port’, 8775), (‘num_networks’, 1), (‘image_ …. …. </syntaxhighlight> This works on my centos-newton but fails in openstack03.controller-0 <syntaxhighlight lang="python"> >>> print CONF.report_interval 2018-03-02 18:11:20.180 11235 CRITICAL demo [req-16f698be-3dd2-4cbc-91f4-46518c33a982 6ce90b4d d6134462 – – a6b9360e] NoSuchOptError: no such option in group DEFAULT: report_interval 2018-03-02 18:11:20.180 11235 ERROR demo Traceback (most recent call last): 2018-03-02 18:11:20.180 11235 ERROR demo File “”, line 1, in 2018-03-02 18:11:20.180 11235 ERROR demo File “/usr/lib/python2.7/site-packages/oslo_config/cfg.py”, line 2187, in __getattr__ 2018-03-02 18:11:20.180 11235 ERROR demo raise NoSuchOptError(name) 2018-03-02 18:11:20.180 11235 ERROR demo NoSuchOptError: no such option in group DEFAULT: report_interval 2018-03-02 18:11:20.180 11235 ERROR demo >>> 2018-03-02 18:13:30.510 11235 CRITICAL demo [req-16f698be-3dd2-4cbc-91f4-46518c33a982 6ce90b4d d6134462 – – a6b9360e] KeyboardInterrupt 2018-03-02 18:13:30.510 11235 ERROR demo KeyboardInterrupt 2018-03-02 18:13:30.510 11235 ERROR demo </syntaxhighlight> Looking at https://review.openstack.org/#/c/468849/ Seems that nova.common is not installed in the server, the script also complains importing it It would be better if I learn without using nova.common 9wyqbp7fa6eczawdst515pk637wers2 Main Page/Openstack Container Configuration Steps 0 38 84 80 2018-09-03T15:01:54Z Eddie0025 30510156 84 wikitext text/x-wiki == Intro == We have seen how to build the containers with kolla, but these containers are not configured at all, lets try to see how they are configured == Containers Steps == First we define our containerized services on THT/environments/docker.yaml <syntaxhighlight lang="yaml"> resource_registry: OS::TripleO::Services::Docker: ../puppet/services/docker.yaml # Default Neutron ML2 puppet plugin to use when NeutronCorePlugin is set to ML2 OS::TripleO::Docker::NeutronMl2PluginBase: ../puppet/services/neutron-plugin-ml2.yaml #NOTE (dprince) add roles to be docker enabled as we support them OS::TripleO::Services::NovaLibvirt: ../docker/services/nova-libvirt.yaml #OS::TripleO::Services::ComputeNeutronOvsAgent: ../docker/services/neutron-ovs-agent.yaml OS::TripleO::Services::NovaCompute: ../docker/services/nova-compute.yaml OS::TripleO::Services::Keystone: ../docker/services/keystone.yaml .. OS::TripleO::Services::NovaScheduler: ../docker/services/nova-scheduler.yaml OS::TripleO::Services::NovaVncProxy: ../docker/services/nova-vnc-proxy.yaml #OS::TripleO::Services::NeutronServer: ../docker/services/neutron-api.yaml #neutron is still not containerized on Pike #OS::TripleO::Services::NeutronApi: ../docker/services/neutron-api.yaml ... ... </syntaxhighlight> The list below represents the correlation between the baremetal and the containers steps. These steps are executed sequentially: <syntaxhighlight> Containers config files generated per hiera settings. Load Balancer configuration baremetal Step 1 baremetal Step 1 containers Core Services (Database/Rabbit/NTP/etc.) Step 2 baremetal Step 2 containers Early Openstack Service setup (Ringbuilder, etc.) Step 3 baremetal Step 3 containers General OpenStack Services Step 4 baremetal Step 4 containers Keystone containers post initialization (tenant, service, endpoint creation) Service activation (Pacemaker) Step 5 baremetal Step 5 containers </syntaxhighlight> If we want to check what is done on each step we should check THT/docker/services/<service>.yaml Lets focus on [https://github.com/openstack/tripleo-heat-templates/blob/master/docker/services/nova-api.yaml nova-api.yaml] , most of it should be valid for other services as well. We can see to following interesting data: <syntaxhighlight lang="yaml"> -puppet_config -kolla_config -docker_config_scripts -docker_config -step_2 -step_3 -step_4 -step_5 -upgrade_tasks </syntaxhighlight> Step3 seems interesting, we can see there how commands are executed on different container each: <syntaxhighlight lang="yaml"> step_3: nova_api_db_sync: start_order: 0 image: *nova_api_image net: host detach: false user: root volumes: &nova_api_bootstrap_volumes list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/config-data/nova/etc/my.cnf.d/tripleo.cnf:/etc/my.cnf.d/tripleo.cnf:ro - /var/lib/config-data/nova/etc/nova/:/etc/nova/:ro - /var/log/containers/nova:/var/log/nova - /var/log/containers/httpd/nova-api:/var/log/httpd command: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage api_db sync'" nova_api_map_cell0: start_order: 1 image: *nova_api_image net: host detach: false user: root volumes: *nova_api_bootstrap_volumes command: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage cell_v2 map_cell0'" nova_api_ensure_default_cell: start_order: 2 image: *nova_api_image net: host detach: false volumes: list_concat: - *nova_api_bootstrap_volumes - - /var/lib/config-data/nova/etc/my.cnf.d/tripleo.cnf:/etc/my.cnf.d/tripleo.cnf:ro - /var/lib/config-data/nova/etc/nova/:/etc/nova/:ro - /var/log/containers/nova:/var/log/nova - /var/lib/docker-config-scripts/nova_api_ensure_default_cell.sh:/nova_api_ensure_default_cell.sh:ro user: root command: "/usr/bin/bootstrap_host_exec nova_api /nova_api_ensure_default_cell.sh" nova_db_sync: start_order: 3 image: *nova_api_image net: host detach: false volumes: *nova_api_bootstrap_volumes user: root command: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage db sync'" </syntaxhighlight> lets examine paunch, you can see these containers are on exited state, since the command is executed once when deploying and then it exists (they run on foreground mode, detach: false ): <syntaxhighlight> # paunch list | grep nova-api | grep step3 | tripleo_step3 | nova_db_sync | 192.168.24.1:8787/rhosp12/openstack-nova-api:2017-12-06.2 | /usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage db sync' | exited | | tripleo_step3 | nova_api_ensure_default_cell | 192.168.24.1:8787/rhosp12/openstack-nova-api:2017-12-06.2 | /usr/bin/bootstrap_host_exec nova_api /nova_api_ensure_default_cell.sh | exited | | tripleo_step3 | nova_api_map_cell0 | 192.168.24.1:8787/rhosp12/openstack-nova-api:2017-12-06.2 | /usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage cell_v2 map_cell0' | exited | | tripleo_step3 | nova_api_db_sync | 192.168.24.1:8787/rhosp12/openstack-nova-api:2017-12-06.2 | /usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage api_db sync' | exited | </syntaxhighlight> Lets try to figure out how containers are configured, it should be done before step3 because, but how ? THT/docker/docker-puppet.py script is responsible for generating the config files for each service. The script is called from the deploy-steps.j2 file and it takes a json file as configuration. The json files passed to this script are built out of the puppet_config parameter set in every service template (explained in the Docker specific settings section). The docker-puppet.py execution results in a oneshot container being executed (usually named puppet-$service_name) to generate the configuration options or run other service specific initialization tasks. Example: Create Keystone endpoints. Lets check its content, just mp_puppet_config function and main: <syntaxhighlight lang="python"> def mp_puppet_config((config_volume, puppet_tags, manifest, config_image, volumes)): ... sh_script = '/var/lib/docker-puppet/docker-puppet.sh' with open(sh_script, 'w') as script_file: os.chmod(script_file.name, 0755) script_file.write("""#!/bin/bash set -ex mkdir -p /etc/puppet cp -a /tmp/puppet-etc/* /etc/puppet rm -Rf /etc/puppet/ssl # not in use and causes permission errors echo "{\\"step\\": $STEP}" > /etc/puppet/hieradata/docker.json TAGS="" if [ -n "$PUPPET_TAGS" ]; then TAGS="--tags \"$PUPPET_TAGS\"" fi ... set +e FACTER_hostname=$HOSTNAME FACTER_uuid=docker /usr/bin/puppet apply \ --detailed-exitcodes --color=false --logdest syslog --logdest console $TAGS /etc/config.pp ... # Disables archiving if [ -z "$NO_ARCHIVE" ]; then archivedirs=("/etc" "/root" "/opt" "/var/lib/ironic/tftpboot" "/var/lib/ironic/httpboot" "/var/www" "/var/spool/cron" "/var/lib/nova/.ssh") rsync_srcs="" for d in "${archivedirs[@]}"; do if [ -d "$d" ]; then rsync_srcs+=" $d" fi done rsync -a -R --delay-updates --delete-after $rsync_srcs /var/lib/config-data/${NAME} mkdir -p /var/lib/config-data/puppet-generated/${NAME} rsync -a -R -0 --delay-updates --delete-after \ --files-from=<(find $rsync_srcs -newer /tmp/the_origin_of_time -not -path '/etc/puppet*' -print0) \ / /var/lib/config-data/puppet-generated/${NAME} tar -c -f - /var/lib/config-data/${NAME} --mtime='1970-01-01' | md5sum | awk '{print $1}' > /var/lib/config-data/${NAME}.md5sum tar -c -f - /var/lib/config-data/puppet-generated/${NAME} --mtime='1970-01-01' | md5sum | awk '{print $1}' > /var/lib/config-data/puppet-generated/${NAME}.md5sum fi """) with tempfile.NamedTemporaryFile() as tmp_man: with open(tmp_man.name, 'w') as man_file: man_file.write('include ::tripleo::packages\n') man_file.write(manifest) rm_container('docker-puppet-%s' % config_volume) pull_image(config_image) dcmd = ['/usr/bin/docker', 'run', '--user', 'root', '--name', 'docker-puppet-%s' % config_volume, '--health-cmd', '/bin/true', '--env', 'PUPPET_TAGS=%s' % puppet_tags, '--env', 'NAME=%s' % config_volume, '--env', 'HOSTNAME=%s' % short_hostname(), '--env', 'NO_ARCHIVE=%s' % os.environ.get('NO_ARCHIVE', ''), '--env', 'STEP=%s' % os.environ.get('STEP', '6'), '--volume', '%s:/etc/config.pp:ro' % tmp_man.name, '--volume', '/etc/puppet/:/tmp/puppet-etc/:ro', '--volume', '/usr/share/openstack-puppet/modules/:/usr/share/openstack-puppet/modules/:ro', '--volume', '%s:/var/lib/config-data/:rw' % os.environ.get('CONFIG_VOLUME_PREFIX', '/var/lib/config-data'), '--volume', 'tripleo_logs:/var/log/tripleo/', # Syslog socket for puppet logs '--volume', '/dev/log:/dev/log', # OpenSSL trusted CA injection '--volume', '/etc/pki/ca-trust/extracted:/etc/pki/ca-trust/extracted:ro', '--volume', '/etc/pki/tls/certs/ca-bundle.crt:/etc/pki/tls/certs/ca-bundle.crt:ro', '--volume', '/etc/pki/tls/certs/ca-bundle.trust.crt:/etc/pki/tls/certs/ca-bundle.trust.crt:ro', '--volume', '/etc/pki/tls/cert.pem:/etc/pki/tls/cert.pem:ro', # script injection '--volume', '%s:%s:rw' % (sh_script, sh_script) ] for volume in volumes: if volume: dcmd.extend(['--volume', volume]) dcmd.extend(['--entrypoint', sh_script]) env = {} # NOTE(flaper87): Always copy the DOCKER_* environment variables as # they contain the access data for the docker daemon. for k in filter(lambda k: k.startswith('DOCKER'), os.environ.keys()): env[k] = os.environ.get(k) if os.environ.get('NET_HOST', 'false') == 'true': log.debug('NET_HOST enabled') dcmd.extend(['--net', 'host', '--volume', '/etc/hosts:/etc/hosts:ro']) dcmd.append(config_image) log.debug('Running docker command: %s' % ' '.join(dcmd)) ######### Here it sems where the containers are launched ################### subproc = subprocess.Popen(dcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) cmd_stdout, cmd_stderr = subproc.communicate() # puppet with --detailed-exitcodes will return 0 for success and no changes # and 2 for success and resource changes. Other numbers are failures if subproc.returncode not in [0, 2]: log.error('Failed running docker-puppet.py for %s' % config_volume) if cmd_stdout: log.error(cmd_stdout) if cmd_stderr: log.error(cmd_stderr) else: if cmd_stdout: log.debug(cmd_stdout) if cmd_stderr: log.debug(cmd_stderr) # only delete successful runs, for debugging rm_container('docker-puppet-%s' % config_volume) log.info('Finished processing puppet configs') return subproc.returncode ######## Here starts main ########## # Holds all the information for each process to consume. # Instead of starting them all linearly we run them using a process # pool. This creates a list of arguments for the above function # to consume. process_map = [] for config_volume in configs: service = configs[config_volume] puppet_tags = service[1] or '' manifest = service[2] or '' config_image = service[3] or '' volumes = service[4] if len(service) > 4 else [] if puppet_tags: puppet_tags = "file,file_line,concat,augeas,cron,%s" % puppet_tags else: puppet_tags = "file,file_line,concat,augeas,cron" process_map.append([config_volume, puppet_tags, manifest, config_image, volumes]) for p in process_map: log.debug('- %s' % p) # Fire off processes to perform each configuration. Defaults # to the number of CPUs on the system. p = multiprocessing.Pool(process_count) returncodes = list(p.map(mp_puppet_config, process_map)) config_volumes = [pm[0] for pm in process_map] success = True for returncode, config_volume in zip(returncodes, config_volumes): if returncode not in [0, 2]: log.error('ERROR configuring %s' % config_volume) success = False # Update the startup configs with the config hash we generated above config_volume_prefix = os.environ.get('CONFIG_VOLUME_PREFIX', '/var/lib/config-data') log.debug('CONFIG_VOLUME_PREFIX: %s' % config_volume_prefix) startup_configs = os.environ.get('STARTUP_CONFIG_PATTERN', '/var/lib/tripleo-config/docker-container-startup-config-step_*.json') log.debug('STARTUP_CONFIG_PATTERN: %s' % startup_configs) infiles = glob.glob('/var/lib/tripleo-config/docker-container-startup-config-step_*.json') for infile in infiles: with open(infile) as f: infile_data = json.load(f) for k, v in infile_data.iteritems(): config_volume = match_config_volume(config_volume_prefix, v) if config_volume: config_hash = get_config_hash(config_volume) if config_hash: env = v.get('environment', []) env.append("TRIPLEO_CONFIG_HASH=%s" % config_hash) log.debug("Updating config hash for %s, config_volume=%s hash=%s" % (k, config_volume, config_hash)) infile_data[k]['environment'] = env outfile = os.path.join(os.path.dirname(infile), "hashed-" + os.path.basename(infile)) with open(outfile, 'w') as out_f: os.chmod(out_f.name, 0600) json.dump(infile_data, out_f) if not success: sys.exit(1) </syntaxhighlight> Remember that the config is stored on in the host/var/lib/config-data/puppet-generated/ directory, and these config files are mounted to the containers <syntaxhighlight lang="json"> # docker inspect <nova_api_container_uuid "Mounts": [ { "Source": "/etc/ssh/ssh_known_hosts", "Destination": "/etc/ssh/ssh_known_hosts", "Mode": "ro", "RW": false, "Propagation": "rprivate" }, { "Source": "/var/lib/kolla/config_files/nova_api.json", "Destination": "/var/lib/kolla/config_files/config.json", "Mode": "ro", "RW": false, "Propagation": "rprivate" }, { "Source": "/var/lib/config-data/puppet-generated/nova", <==== "Destination": "/var/lib/kolla/config_files/src", "Mode": "ro", "RW": false, "Propagation": "rprivate" } </syntaxhighlight> I need to clarify how /etc/nova/ reaches the the container since config files are mounted on /var/lib/kolla/config_files/src, perhaps the the mounted files are merged with the root filesystem ? == Full nova-api.yaml == <syntaxhighlight lang="yaml"> heat_template_version: pike description: > OpenStack containerized Nova API service parameters: DockerNovaApiImage: description: image type: string DockerNovaConfigImage: description: The container image to use for the nova config_volume type: string EndpointMap: default: {} description: Mapping of service endpoint -> protocol. Typically set via parameter_defaults in the resource registry. type: json ServiceData: default: {} description: Dictionary packing service data type: json ServiceNetMap: default: {} description: Mapping of service_name -> network name. Typically set via parameter_defaults in the resource registry. This mapping overrides those in ServiceNetMapDefaults. type: json DefaultPasswords: default: {} type: json RoleName: default: '' description: Role name on which the service is applied type: string RoleParameters: default: {} description: Parameters specific to the role type: json EnableInternalTLS: type: boolean default: false UpgradeRemoveUnusedPackages: default: false description: Remove package if the service is being disabled during upgrade type: boolean DeployIdentifier: default: '' type: string description: > Setting this to a unique value will re-run any deployment tasks which perform configuration on a Heat stack-update. conditions: internal_tls_enabled: {equals: [{get_param: EnableInternalTLS}, true]} resources: ContainersCommon: type: ./containers-common.yaml MySQLClient: type: ../../puppet/services/database/mysql-client.yaml NovaApiBase: type: ../../puppet/services/nova-api.yaml properties: EndpointMap: {get_param: EndpointMap} ServiceData: {get_param: ServiceData} ServiceNetMap: {get_param: ServiceNetMap} DefaultPasswords: {get_param: DefaultPasswords} RoleName: {get_param: RoleName} RoleParameters: {get_param: RoleParameters} outputs: role_data: description: Role data for the Nova API role. value: service_name: {get_attr: [NovaApiBase, role_data, service_name]} config_settings: map_merge: - get_attr: [NovaApiBase, role_data, config_settings] - apache::default_vhost: false logging_source: {get_attr: [NovaApiBase, role_data, logging_source]} logging_groups: {get_attr: [NovaApiBase, role_data, logging_groups]} step_config: &step_config list_join: - "\n" - - "['Nova_cell_v2'].each |String $val| { noop_resource($val) }" - {get_attr: [NovaApiBase, role_data, step_config]} - {get_attr: [MySQLClient, role_data, step_config]} service_config_settings: {get_attr: [NovaApiBase, role_data, service_config_settings]} # BEGIN DOCKER SETTINGS puppet_config: config_volume: nova puppet_tags: nova_config step_config: *step_config config_image: {get_param: DockerNovaConfigImage} kolla_config: /var/lib/kolla/config_files/nova_api.json: command: /usr/sbin/httpd -DFOREGROUND config_files: - source: "/var/lib/kolla/config_files/src/*" dest: "/" merge: true preserve_properties: true permissions: - path: /var/log/nova owner: nova:nova recurse: true /var/lib/kolla/config_files/nova_api_cron.json: command: /usr/sbin/crond -n config_files: - source: "/var/lib/kolla/config_files/src/*" dest: "/" merge: true preserve_properties: true permissions: - path: /var/log/nova owner: nova:nova recurse: true docker_config_scripts: nova_api_discover_hosts.sh: mode: "0700" content: | #!/bin/bash export OS_PROJECT_DOMAIN_NAME=$(crudini --get /etc/nova/nova.conf keystone_authtoken project_domain_name) export OS_USER_DOMAIN_NAME=$(crudini --get /etc/nova/nova.conf keystone_authtoken user_domain_name) export OS_PROJECT_NAME=$(crudini --get /etc/nova/nova.conf keystone_authtoken project_name) export OS_USERNAME=$(crudini --get /etc/nova/nova.conf keystone_authtoken username) export OS_PASSWORD=$(crudini --get /etc/nova/nova.conf keystone_authtoken password) export OS_AUTH_URL=$(crudini --get /etc/nova/nova.conf keystone_authtoken auth_url) export OS_AUTH_TYPE=password export OS_IDENTITY_API_VERSION=3 echo "(cellv2) Running cell_v2 host discovery" timeout=600 loop_wait=30 declare -A discoverable_hosts for host in $(hiera -c /etc/puppet/hiera.yaml cellv2_discovery_hosts | sed -e '/^nil$/d' | tr "," " "); do discoverable_hosts[$host]=1; done timeout_at=$(( $(date +"%s") + ${timeout} )) echo "(cellv2) Waiting ${timeout} seconds for hosts to register" finished=0 while : ; do for host in $(openstack -q compute service list -c 'Host' -c 'Zone' -f value | awk '$2 != "internal" { print $1 }'); do if (( discoverable_hosts[$host] == 1 )); then echo "(cellv2) compute node $host has registered" unset discoverable_hosts[$host] fi done finished=1 for host in "${!discoverable_hosts[@]}"; do if (( ${discoverable_hosts[$host]} == 1 )); then echo "(cellv2) compute node $host has not registered" finished=0 fi done remaining=$(( $timeout_at - $(date +"%s") )) if (( $finished == 1 )); then echo "(cellv2) All nodes registered" break elif (( $remaining <= 0 )); then echo "(cellv2) WARNING: timeout waiting for nodes to register, running host discovery regardless" echo "(cellv2) Expected host list:" $(hiera -c /etc/puppet/hiera.yaml cellv2_discovery_hosts | sed -e '/^nil$/d' | sort -u | tr ',' ' ') echo "(cellv2) Detected host list:" $(openstack -q compute service list -c 'Host' -c 'Zone' -f value | awk '$2 != "internal" { print $1 }' | sort -u | tr '\n', ' ') break else echo "(cellv2) Waiting ${remaining} seconds for hosts to register" sleep $loop_wait fi done echo "(cellv2) Running host discovery..." su nova -s /bin/bash -c "/usr/bin/nova-manage cell_v2 discover_hosts --verbose" nova_api_ensure_default_cell.sh: mode: "0700" content: | #!/bin/bash DEFID=$(nova-manage cell_v2 list_cells | sed -e '1,3d' -e '$d' | awk -F ' *| *' '$2 == "default" {print $4}') if [ "$DEFID" ]; then echo "(cellv2) Updating default cell_v2 cell $DEFID" su nova -s /bin/bash -c "/usr/bin/nova-manage cell_v2 update_cell --cell_uuid $DEFID --name=default" else echo "(cellv2) Creating default cell_v2 cell" su nova -s /bin/bash -c "/usr/bin/nova-manage cell_v2 create_cell --name=default" fi docker_config: # db sync runs before permissions set by kolla_config step_2: nova_init_logs: image: &nova_api_image {get_param: DockerNovaApiImage} privileged: false user: root volumes: - /var/log/containers/nova:/var/log/nova - /var/log/containers/httpd/nova-api:/var/log/httpd command: ['/bin/bash', '-c', 'chown -R nova:nova /var/log/nova'] step_3: nova_api_db_sync: start_order: 0 image: *nova_api_image net: host detach: false user: root volumes: &nova_api_bootstrap_volumes list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/config-data/nova/etc/my.cnf.d/tripleo.cnf:/etc/my.cnf.d/tripleo.cnf:ro - /var/lib/config-data/nova/etc/nova/:/etc/nova/:ro - /var/log/containers/nova:/var/log/nova - /var/log/containers/httpd/nova-api:/var/log/httpd command: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage api_db sync'" nova_api_map_cell0: start_order: 1 image: *nova_api_image net: host detach: false user: root volumes: *nova_api_bootstrap_volumes command: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage cell_v2 map_cell0'" nova_api_ensure_default_cell: start_order: 2 image: *nova_api_image net: host detach: false volumes: list_concat: - *nova_api_bootstrap_volumes - - /var/lib/config-data/nova/etc/my.cnf.d/tripleo.cnf:/etc/my.cnf.d/tripleo.cnf:ro - /var/lib/config-data/nova/etc/nova/:/etc/nova/:ro - /var/log/containers/nova:/var/log/nova - /var/lib/docker-config-scripts/nova_api_ensure_default_cell.sh:/nova_api_ensure_default_cell.sh:ro user: root command: "/usr/bin/bootstrap_host_exec nova_api /nova_api_ensure_default_cell.sh" nova_db_sync: start_order: 3 image: *nova_api_image net: host detach: false volumes: *nova_api_bootstrap_volumes user: root command: "/usr/bin/bootstrap_host_exec nova_api su nova -s /bin/bash -c '/usr/bin/nova-manage db sync'" step_4: nova_api: start_order: 2 image: *nova_api_image net: host user: root privileged: true restart: always volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/nova_api.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/nova/:/var/lib/kolla/config_files/src:ro - /var/log/containers/nova:/var/log/nova - /var/log/containers/httpd/nova-api:/var/log/httpd - if: - internal_tls_enabled - /etc/pki/tls/certs/httpd:/etc/pki/tls/certs/httpd:ro - '' - if: - internal_tls_enabled - /etc/pki/tls/private/httpd:/etc/pki/tls/private/httpd:ro - '' environment: - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS nova_api_cron: image: *nova_api_image net: host user: root privileged: false restart: always healthcheck: test: /bin/true volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/nova_api_cron.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/nova/:/var/lib/kolla/config_files/src:ro - /var/log/containers/nova:/var/log/nova - /var/log/containers/httpd/nova-api:/var/log/httpd environment: - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS step_5: nova_api_discover_hosts: start_order: 1 image: *nova_api_image net: host detach: false volumes: list_concat: - *nova_api_bootstrap_volumes - - /var/lib/config-data/nova/etc/my.cnf.d/tripleo.cnf:/etc/my.cnf.d/tripleo.cnf:ro - /var/lib/config-data/nova/etc/nova/:/etc/nova/:ro - /var/log/containers/nova:/var/log/nova - /var/lib/docker-config-scripts/nova_api_discover_hosts.sh:/nova_api_discover_hosts.sh:ro user: root command: "/usr/bin/bootstrap_host_exec nova_api /nova_api_discover_hosts.sh" environment: # NOTE: this should force this container to re-run on each # update (scale-out, etc.) - list_join: - '' - - 'TRIPLEO_DEPLOY_IDENTIFIER=' - {get_param: DeployIdentifier} metadata_settings: get_attr: [NovaApiBase, role_data, metadata_settings] host_prep_tasks: - name: create persistent logs directory file: path: "{{ item }}" state: directory with_items: - /var/log/containers/nova - /var/log/containers/httpd/nova-api upgrade_tasks: - name: Stop and disable nova_api service tags: step2 service: name=openstack-nova-api state=stopped enabled=no - name: Remove openstack-nova-api package if operator requests it yum: name=openstack-nova-api state=removed tags: step2 ignore_errors: True when: {get_param: UpgradeRemoveUnusedPackages} - name: remove old nova cron jobs tags: step2 file: path: /var/spool/cron/nova state: absent </syntaxhighlight> To know the command line that will be used for a specific container you can use: <syntaxhighlight> $ sudo paunch debug --file /var/lib/tripleo-config/docker-container-startup-config-step_3.json --container ironic_db_sync --action print-cmd </syntaxhighlight> For more information [https://docs.openstack.org/tripleo-docs/latest/install/containers_deployment/architecture.html] ifj0utjcedh2kt7wqcsepvxj6zqgr95 Main Page/Openstack Host Steps 0 39 81 2018-08-31T14:04:10Z Eddie0025 30510156 Created page with "We have seen what happens inside the containers during the installation, but what happens on the host ? First we run HostPrepDeployment (deploy-steps.j2) It runs: - Puppe..." 81 wikitext text/x-wiki We have seen what happens inside the containers during the installation, but what happens on the host ? First we run HostPrepDeployment (deploy-steps.j2) It runs: - Puppet step N on host - Step N in Containersa - Other Containerized puppet tasks ( only on botstrap host, like creating keystone endpints) bkm0xvcr5d6n0e9gm82h06upfn0jm3q User:Eddie0025/modern.css 2 34 56 55 2018-07-13T16:27:48Z Eddie0025 30510156 56 css text/css #mw-content-text { font-size: 15px; } sc45m802dpg6dhlreoyuy7aolr2lu5h User:MediaWiki default 2 23 35 34 2010-12-30T05:43:26Z MediaWiki default 30443056 35 wikitext text/x-wiki This account is used by [[s:ShoutWiki Staff|ShoutWiki Staff]] when performing maintenance tasks. This account is not a bot and cannot be blocked. If there is a problem with an edit from this account, please inform a member of the [[s:Customer Support Team|Customer Support Team]] using [[Special:Contact]]. Thanks, ShoutWiki Staff 8u83a4eosok8vsr2v7vagsq052zlpfg User talk:Cook879 3 27 41 40 2012-09-08T10:46:56Z MediaWiki default 30443056 41 wikitext text/x-wiki {| align="center" style="background: #ccf; border: 3px solid #8888AA; width: 100%; -moz-border-radius: 80px;" |- | Hi. Welcome to my talk page. Feel free to [http://{{SERVERNAME}}/w/index.php?title=User_talk:Cook879&action=edit&section=new post a message] below. |} r3ikw28tsv3q58cksiya005d2t1n0ig User talk:Eddie0025 3 32 48 2018-07-13T15:24:19Z ShoutWiki 11 48 wikitext text/x-wiki Hi Eddie0025, thank you for choosing ShoutWiki to make your wiki. We would suggest that you start your wiki off by doing these few basic things: *Upload a logo. You can do this by uploading an image over [[:File:Wiki.png]]. (not available on some skins) *Design your [[Main Page]]. The main page is likely the first thing users will see. It should be attractive and catch the eye. *Start building content. All wikis need content to become the best they can be. If you need help with making a logo, skin or favicon, please see [[s:w:logocreation|ShoutWiki's Logo Creation Wiki]]. If you need any help with building your wiki, feel free to contact [[s:ShoutWiki Staff|ShoutWiki staff]] either via their talk pages or via [[Special:Contact]]. Alternatively, you can talk to us, or other users, via [[s:ShoutWiki Hub:IRC|IRC]]. Thank you again for using ShoutWiki. [[s:ShoutWiki Staff|ShoutWiki staff]] 15:23, 13 July 2018 admb2006iv2m221kz1ciu828svinfg4 User talk:Lcawte 3 29 43 2013-03-28T18:59:56Z MediaWiki default 30443056 43 wikitext text/x-wiki {{s::User talk:Lcawte/header}} 68cjp69hrs0otmdn18l1a2b85wzrzyp User talk:Solar Dragon 3 31 46 45 2013-08-21T21:30:04Z MediaWiki default 30443056 46 wikitext text/x-wiki {{s::User:Solar Dragon/Talkheader}} o2y3a4p2midvn09l97rwprgfdpfgdbp File:Wiki.png 6 28 42 2012-09-13T14:06:18Z MediaWiki default 30443056 42 wikitext text/x-wiki Wiki logo. Upload a new image over this one to set your own logo. dgwmv2n7qsfzlck7bqxtq40b45oxer2 Template:HeaderTemplate 10 7 12 2009-05-02T18:34:55Z MediaWiki default 30443056 12 wikitext text/x-wiki <div> <!-- Beginning of header section --> {|style="width:100%;margin-top:+.7em;background-color:#4682B4;border:1px solid #ccc;-moz-border-radius:20px" |style="width:45%;color:#000"| {|style="width:100%;border:solid 0px;background:none" |- |style="width:100%px;text-align:center;white-space:nowrap;color:#000" | <div style="font-size:195%;border:none;margin: 0;padding:.1em;color:#FFFFFF">{{{welcome}}}</div> |}<!-- Blurb & useful links --> |style="width:45%;font-size:125%;color:#FFFFFF"| {{{blurb}}} |}<!-- End of blurb & useful links --> </div> j3mqpp6bt8r07sw2xdrt404pvemv0ha Template:MainTemplate 10 9 18 14 2009-07-08T08:41:15Z MediaWiki default 30443056 18 wikitext text/x-wiki {{HeaderTemplate|welcome={{{welcome}}}|blurb={{{blurb}}}}} <br /> <!-- LEFT COLUMN --> {| width="100%" cellspacing="0" cellpadding="0" style="background:transparent;" |- | width="50%" style="vertical-align:top; padding-right:0.5em;" | <!-- Info about this site --> {{SectionTemplate|title={{{about_title}}}|content={{{about_content}}}}} | width="50%" style="vertical-align:top; padding-left:0.5em;" | <!-- Featured Article --> {{SectionTemplate|title={{{featured_title}}}|content={{{featured_content}}}}} |} <br /> <!-- RIGHT COLUMN --> {| width="100%" cellspacing="0" cellpadding="0" style="background:transparent;" |- | width="50%" style="vertical-align:top; padding-right:0.5em;" | <!-- Did you know... --> {{SectionTemplate|title={{{didyouknow_title}}}|content={{{didyouknow_content}}}}} | width="50%" style="vertical-align:top; padding-left:0.5em;" | <!-- Site news --> {{SectionTemplate|title={{{news_title}}}|content={{{news_content}}}}} |} __NOTOC__ __NOEDITSECTION__ e4p99tjrg6tq47iqlh9ln9ua3v35z2z Template:SectionTemplate 10 8 20 13 2009-07-12T21:34:10Z MediaWiki default 30443056 20 wikitext text/x-wiki <h2 style="border:none; background-color:#4682B4; padding:0.2em 0; margin:0; color:#ffffff; font-size:125%; font-weight:bold; text-indent:0.5em; font-variant:small-caps; -moz-border-radius: 10px">{{{title}}}</h2> <div style="margin-bottom:1em; padding:0.5em 0.8em 0.5em 0.8em;"> {{{content}}} </div> j5b1lar8shlr44bgt4p6ns6h3e72b0p Category:Browse 14 13 24 2009-12-30T17:56:16Z MediaWiki default 30443056 24 wikitext text/x-wiki This is a starting point which can be used to access any article on this wiki. [[Category:Browse]] 5s3x2nudvhqwi71yepyzbt5ozp3acmm Category:Templates 14 12 23 2009-12-30T17:55:03Z MediaWiki default 30443056 23 wikitext text/x-wiki This category is for '''Templates'''. [[Category:Browse]] jpvy9lwat2x4w625g8zef5ao6t97drj Category:Utility templates 14 11 22 2009-12-30T17:54:25Z MediaWiki default 30443056 22 wikitext text/x-wiki This category is for '''Utility templates'''. [[Category:Templates]] 2k1og0eh9magim62rcbfxwmcn1sxnrf